package cn.wolfcode.wolf2w.redis.service.impl;

import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.redis.service.IStrategyStatisVORedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.redis.vo.StrategyStatisVO;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatisVORedisServiceImpl implements IStrategyStatisVORedisService{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IStrategyService strategyService;

    //  设置攻略阅读数
    @Override
    public void viewnumIncrease(String sid, int num) {
        //  拼接字符串当做key
        String key = RedisKeys.STRATEGT_STATIS_VO.join(sid);
        //  获取StrategyStatisVo对象
        StrategyStatisVO strategyStatisVo = this.getStrategyStatisVo(sid);

        //  阅读数加1
        strategyStatisVo.setViewnum(strategyStatisVo.getViewnum() + 1);
        //  设置到缓存中
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(strategyStatisVo));
    }

    //  获取StrategyStatisVo对象
    @Override
    public StrategyStatisVO getStrategyStatisVo(String sid) {
        //  拼接字符串当做key
        String key = RedisKeys.STRATEGT_STATIS_VO.join(sid);

        //  创建一个对象用来存储
        StrategyStatisVO strategyStatisVO = null;

        //  判断缓存中是否存在拼接的key
        if (stringRedisTemplate.hasKey(key)) {
            //  若存在，直接获取value
            String value = stringRedisTemplate.opsForValue().get(key);
            //  再转为对象，赋值给上面strategyStatisVO
            strategyStatisVO = JSON.parseObject(value, StrategyStatisVO.class);
        } else {
            //  若不存在，初始化strategyStatisVO
            strategyStatisVO = new StrategyStatisVO();
            // 通过id查询攻略明细
            Strategy strategy = strategyService.selectById(sid);
            //  再设置到strategyStatisVO中
            BeanUtils.copyProperties(strategy, strategyStatisVO);
            strategyStatisVO.setStrategyId(strategy.getId());
            //  设置到redis缓存中
            stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(strategyStatisVO));
        }
        return strategyStatisVO;
    }

    //  设置StrategyStatisVo对象
    @Override
    public void setStrategyStatisVo(StrategyStatisVO strategyStatisVo) {
        //  拼接字符串当做key
        String key = RedisKeys.STRATEGT_STATIS_VO.join(strategyStatisVo.getStrategyId());
        //  设置到redis缓存中
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(strategyStatisVo));
    }

    //  设置攻略评论数
    @Override
    public void replynumIncrease(String strategyId, int num) {
        //  拼接字符串当做key
        String key = RedisKeys.STRATEGT_STATIS_VO.join(strategyId);
        //  获取strategyStatisVo对象
        StrategyStatisVO strategyStatisVo = this.getStrategyStatisVo(strategyId);

        //  评论数加1
        strategyStatisVo.setReplynum(strategyStatisVo.getReplynum() + num);
        //  添加到redis缓存中
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(strategyStatisVo));
    }

    //  收藏成功/取消收藏成功
    @Override
    public boolean setFavornum(String sid, String uid) {
        //  拼接字符串当做key
        String key = RedisKeys.STRATEGT_USER_FAVOR.join(uid);

        //  定义一个集合用来存储sid
        List<String> sidList = new ArrayList<>();

        //  判断当前sid是否存在缓存中
        if (stringRedisTemplate.hasKey(key)) {
            //  若存在，则通过key找到对应的value值
            String value = stringRedisTemplate.opsForValue().get(key);
            //  将它添加到存储sid的集合中
            sidList = JSON.parseArray(value, String.class);
        }

        //  设置一个标记
        boolean flag = false;
        //  通过sid获取strategyStatisVo对象
        StrategyStatisVO strategyStatisVo = this.getStrategyStatisVo(sid);
        //  判断该攻略是否储存在sid集合中
        if (sidList.contains(sid)) {
            //  若存在，则说明该攻略已经被收藏成功
            //  strategyStatisVo对象中的收藏数需要-1
            strategyStatisVo.setFavornum(strategyStatisVo.getFavornum() - 1);
            //  把当前攻略的id移除sid集合中
            sidList.remove(sid);
            //  反之
        } else {
            strategyStatisVo.setFavornum(strategyStatisVo.getFavornum() + 1);
            sidList.add(sid);
            flag = true;
        }

        //  更新sid集合
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(sidList));
        //  更新vo对象
        this.setStrategyStatisVo(strategyStatisVo);

        return flag;
    }

    //  设置顶操作
    @Override
    public boolean setThumbsupnum(String sid, String uid) {

        //  拼接key
        String key = RedisKeys.STRATEGT_THUMBSUP.join(uid, sid);
        String join = RedisKeys.STRATEGT_STATIS_VO.join(sid);

        //  判断该key是否存在redis中
        //  若不存在，则说明当前没有顶操作
        if (!stringRedisTemplate.hasKey(key)) {

            //  获取当前的vo对象
            StrategyStatisVO strategyStatisVo = this.getStrategyStatisVo(sid);
            //  设置点赞数+1
            strategyStatisVo.setThumbsupnum(strategyStatisVo.getThumbsupnum() + 1);
            //  更新vo对象
            stringRedisTemplate.opsForValue().set(join, JSON.toJSONString(strategyStatisVo));

            //  获取当前时间
            Date nowDate = DateUtil.getTime();
            //  获取当前最后一秒的时间
            Date endDate = DateUtil.getEndDate(nowDate);
            //  用当前最后一秒的时间减去当前时间，得到时间差
            long timeNum = DateUtil.getDateBetween(endDate, nowDate);
            //  此时间就是该点赞时，需要存货的时间
            //  更新
            stringRedisTemplate.opsForValue().set(key, "1", timeNum, TimeUnit.SECONDS);
            return true;
        }

        return false;
    }

    //  判断缓存中是否存在数据库的数据
    @Override
    public boolean isStrategyVoExists(String sid) {
        String key = RedisKeys.STRATEGT_STATIS_VO.join(sid);
        return stringRedisTemplate.hasKey(key);
    }

    //  查询redis中所有的vo对象
    @Override
    public List<StrategyStatisVO> queryStrategyVoByPattern(String pattern) {
        //  创建一个集合用来存储vo对象
        List<StrategyStatisVO> strategyStatisVOList = new ArrayList<>();

        //  通过前缀拼接拿到keyPattern
        String keyPattern = RedisKeys.STRATEGT_STATIS_VO.join(pattern);

        //  查询出所有的key值
        Set<String> keys = stringRedisTemplate.keys(keyPattern);
        //  遍历key值
        for (String key : keys) {
            //  通过key去获取value值
            String value = stringRedisTemplate.opsForValue().get(key);
            //  把value值转成vo对象添加到vo集合中
            strategyStatisVOList.add(JSON.parseObject(value, StrategyStatisVO.class));
        }

        //  返回vo对象集合
        return strategyStatisVOList;
    }

}
